/* eslint-disable react-hooks/rules-of-hooks */
import { hash } from "ohash";
interface RequestParams extends RequestInit {
  params?: any;
  allUrl?: string;
  isJSON?: boolean;
}

const useFetch = async (url: string, options?: RequestParams) => {
  const reqUrl = options?.allUrl + url;
  const key = hash(JSON.stringify(options) + url);
  const customHeaders = {
    "Content-Type": "application/json",
    Accept: "application/json",
    ...options?.headers,
  };

  try {
    if ((options as any).headers["Content-Type"] == "undefined") {
      delete (customHeaders as any)["Content-Type"];
    }
  } catch {}
  const customOptions = {
    ...options,
    body:
      Object.prototype.toString.call(options?.body) === "[object FormData]"
        ? options?.body
        : JSON.stringify(options?.body),
  };
  let response;
  if (options?.params) {
    response = await fetch(reqUrl + new URLSearchParams(options.params), {
      ...options,
      key,
      headers: customHeaders,
    } as any);
  } else {
    response = await fetch(reqUrl, {
      ...customOptions,
      key,
      headers: customHeaders,
    } as any);
  }
  if (options?.isJSON?.toString()) {
    return response;
  }
  const data = await response.json();
  return data;
};
interface resqOptions {
  isJSON?: boolean;
  method?: string;
  params?: any;
  signal?: AbortSignal;
  allUrl?: string;
  headers?: { [key: string]: string };
  body?: any;
}

export default class Http {
  get(url?: string, options?: resqOptions) {
    return useFetch(url!, { method: "get", ...options });
  }

  post(url?: string, options?: resqOptions) {
    return useFetch(url!, { method: "post", ...options });
  }

  put(url?: string, body?: any) {
    return useFetch(url!, { method: "put", body });
  }

  delete(url?: string, params?: any) {
    return useFetch(url!, { method: "delete", params });
  }
}
